#!/usr/bin/env python
# -* coding: utf-8 -*-

#Author: Gustaw Lewandowski
#Licence : GPL

import sys
import os
import editpanel
import time
import shutil
import urwid
import encodings
from utils import AreYouSureForMulti, InputDialog, AreYouSureDialog, utf8decode, setup, log

from mutex import mutex

urwidcmd = 'urwidcmd'

class UrwidCmdProc():
	"""
	Class for executing command sending by all modules. 
	It uses urwid key codes for comunication.
	"""
	
	# command codes
	rename		= 1
	delete		= 2
	copy		= 3
	move		= 4
	restore 	= 5
	mdelete		= 6
	mcopy		= 7
	mmove		= 8
	rmemptydir 	= 9
	mkdir		= 10
	edit		= 11

	def __init__(self, cmd, view):
		self.cmd = [i for i in cmd[1:]]
		log.info(self.cmd)
		self.view = view
		if cmd[1] == self.rename:
			if os.path.exists(cmd[3]):
				s = "Overwrite \'" + cmd[3] + "\'?"
				view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
			else:
				self.do()
		elif cmd[1] == self.delete:
			if os.path.isdir(cmd[2]) == True:
				dc = os.listdir(cmd[2])
				if len(dc) == 0:
					s = "Delete empty directory \'" + cmd[2] + "\'?"
					self.cmd[0] = self.rmemptydir
					view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
				else:
					self.do_rm(dc, cmd[2], True)
			else:
				s = "Delete file \'" + cmd[2] + "\'?"
				view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
		elif cmd[1] == self.copy:
			#joined = os.path.join(cmd[3], cmd[2])
			if os.path.exists(cmd[3]):
				s = "Overwrite \'" + cmd[3] + "\'?"
				view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
			else:
				s = "Copy \'" + cmd[2] + "\' to \'" + cmd[3] + "\' directory?"
				view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
		elif cmd[1] == self.mcopy:
			s = "Copy " + str(len(cmd[2])) + " files to \'" + cmd[3] + "\' directory?"
			view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
		elif cmd[1] == self.move:
			#s = "Move \'" + cmd[2] + "\' to \'" + cmd[3] + "\' directory?"
			#view.set_body(AreYouSureDialog(view.get_body(), log, s, self.back))
			view.set_body(InputDialog(view.get_body(), cmd[3], self.back))
		elif cmd[1] == self.mmove:
			s = "Move " + str(len(cmd[2])) + " files to \'" + cmd[3] + "\' directory?"
			view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
		elif cmd[1] == self.mdelete:
			s = "Delete " + str(len(cmd[2])) + " files?"
			view.set_body(AreYouSureDialog(view.get_body(), s, self.back))
		elif cmd[1] == self.mkdir:
			s = "Create new directory " + str(len(cmd[2])) + " files?"
			view.set_body(InputDialog(view.get_body(), s, self.back))
		elif cmd[1] == self.edit:
			view.set_body(editpanel.EditPanel(cmd[2], view.get_body()))
		elif cmd[1] == self.restore:
			if cmd[2] == None:
				raise urwid.ExitMainLoop()
			# restore previous body
			view.set_body(cmd[2])
	def do(self):
		found_problem = False
		if self.cmd[0] == self.rename:
			try:
				shutil.move(self.cmd[1], self.cmd[2])
			except (IOError, os.error), why:
				log.error("Can't copy %s to %s: %s" % (`self.cmd[1]`, `self.cmd[2]`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('rename ' + self.cmd[1] + ' -> ' + self.cmd[2])
					self.view.get_body().refresh_focus_dir()
		elif self.cmd[0] == self.delete:
			try:
				os.remove(self.cmd[1])
			except (IOError, os.error), why:
				log.error("Can't delete %s: %s" % (`self.cmd[1]`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('delete ' + self.cmd[1])
					self.view.get_body().refresh_focus_dir()
		elif self.cmd[0] == self.rmemptydir:
			try:
				shutil.rmtree(self.cmd[1])
			except (IOError, os.error), why:
				log.error("Can't delete empty dir %s: %s" % (`self.cmd[1]`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('delete empty dir ' + self.cmd[1])
					self.view.get_body().refresh_focus_dir()
		elif self.cmd[0] == self.mdelete:
			try:
				for x in self.cmd[1]:
					os.remove(x)
			except (IOError, os.error), why:
				log.error("Can't delete %s: %s" % (`self.cmd[1]`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('delete ' + `self.cmd[1]`)
					self.view.get_body().refresh_focus_dir()
		elif self.cmd[0] == self.copy:
			try:
				if os.path.isdir(self.cmd[1]):
					shutil.copytree(self.cmd[1], self.cmd[2])
				else:
					shutil.copy2(self.cmd[1], self.cmd[2])
			except (IOError, os.error), why:
				log.error("Can't copy %s to %s: %s" % (`self.cmd[1]`, `self.cmd[2]`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('copy ' + self.cmd[1] + ' to ' + self.cmd[2])
					self.view.get_body().refresh_dirs()
		elif self.cmd[0] == self.mcopy:
			try:
				for x in self.cmd[1]:
					shutil.copy2(x, self.cmd[2])
			except (IOError, os.error), why:
				log.error("Can't copy %s to %s: %s" % (`self.cmd[1]`, `self.cmd[2]`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('copy ' + `self.cmd[1]` + ' to ' + self.cmd[2])
					self.view.get_body().refresh_dirs()
		elif self.cmd[0] == self.move:
			try:
				shutil.move(self.cmd[1], self.cmd[2])
			except (IOError, os.error), why:
				log.error("Can't move %s to %s: %s" % (`self.cmd[1]`, `self.cmd[2]+"/"`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('move ' + self.cmd[1] + ' to ' + self.cmd[2])
					self.view.get_body().refresh_dirs()
		elif self.cmd[0] == self.mmove:
			try:
				for x in self.cmd[1]:
					shutil.move(x, self.cmd[2])
			except (IOError, os.error), why:
				log.error("Can't move %s to %s: %s" % (`self.cmd[1]`, `self.cmd[2]`, str(why)))
				self.showError(why)
				found_problem = True
			finally:
				if found_problem == False:
					log.info('move ' + `self.cmd[1]` + ' to ' + self.cmd[2])
					self.view.get_body().refresh_dirs()
	def showError(self, why):
		self.view.set_body(FailureWindow(self.view.get_body(), log, str(why), self.dummy_back))
	def do_rm(self, dc, directory, root=False):
		m = mutex()
		m.locked = 1
		m.lock(self.do_rm_dir, (directory, root))
		dialog  = AreYouSureForMulti(self.view, "", self.do_rm_file, m)
		for file_name in dc:
			file_name = os.path.join(directory, file_name)
			if os.path.isdir(file_name) == True:
				self.do_rm(os.listdir(file_name), file_name)
			else:
				dialog.question(file_name)

	def do_rm_file(self, file_name):
		try:
			os.remove(file_name)
		except (IOError, os.error), why:
			log.error("Can't delete %s: %s" % (`file_name`, str(why)))
			return False
		finally:
			log.info('delete ' + file_name)
			return True

	def do_rm_dir(self, pack):
		directory, final = pack
		try:
			shutil.rmtree(directory)
		except (IOError, os.error), why:
			log.error("Can't delete %s: %s" % (`directory`, str(why)))
		finally:
			log.info('delete ' + directory)
			if final == True:
				self.view.get_body().refresh_focus_dir()

	def back(self, button):
		self.view.set_body(self.view.get_body().bottom_w)
		if button.exitcode == 0:
			log.info('accept')
			self.do()
		else:
			log.info('decline')
	def dummy_back(self, button):
		self.view.set_body(self.view.get_body().bottom_w)

def isUCP(rc):
	if type(rc) == type(()) and rc[0].find(urwidcmd) >= 0:
		return True
	return False

__all__ = ['UrwidCmdProc', 'urwidcmd', 'isUCP']
